Explanation:

To get how passing extra argument to shellcode works read explanation here first: Comfy direct syscall caller (x64)

You might be familiar with the easy way of spoofing return addresses on x86, especially for thiscall/fastcall/stdcall where it only consists of finding a `ret` in the game module, and using it as a trampoline. On x64 however, due to the x64 fastcall it becomes a bit harder to do this nicely, since you have caller cleanup and red zone. What I decided to do is using a nonvolatile register to get the original return address, and find a gadget in the game that jumps based on a nonvolatile register (`jmp [rbx]` in my code)

What this code does is creating a temp storage for the shellcode on the stack, put the gadget address and called function address in there, and reserves an extra 8 bytes for the shellcode. After this using the way described in the linked thread the address of this storage is passed to the shellcode, which reads these to registers, and stores the shellcode's return address, the original return address, and the original content of the nonvolatile register (rbx) in there.
After this it puts the address of the storage into that register, to get it preserved, and jumps into the called function. The function runs, then returns to the gadget we used (`jmp [rbx]`), which in turn continues with executing the rest of our shellcode.
The remaining shellcode restores rbx, aligns stack, and "returns" (implemented by a jmp due to the changed address of the return address).

How can I modify this?

You can use any nonvolatile register, my choice was rbx because of its short encoding: